package com.yangrd.helper.crudhelper.api;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yangrd.helper.crudhelper.common.AmisPage;
import com.yangrd.helper.crudhelper.common.Result;
import com.yangrd.helper.crudhelper.core.crud.ctrl.CrudCtrlService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author yangrd
 * @date 2019/3/22
 **/
@Slf4j
@RequiredArgsConstructor


@RestController
@RequestMapping("/${crud-helper.context-path:/admin}")
public class CrudCtrlController {

    private final CrudCtrlService crudCtrlService;

    @PostMapping("/{domain}")
    @ResponseStatus(HttpStatus.CREATED)
    public Result<Object> create(@PathVariable String domain, @RequestBody String reqBody) {
        return Result.success(crudCtrlService.save(domain, reqBody));
    }

    @DeleteMapping("/{domain}")
    public Result<Object> delete(@PathVariable String domain, @RequestParam("ids") List<String> ids) {
        crudCtrlService.delete(domain, ids);
        return Result.success();
    }

    @PutMapping("/{domain}/{id}")
    public Result<Object> update(@PathVariable String domain, @PathVariable String id, @RequestBody String reqBody) {
        crudCtrlService.update(domain, id, reqBody);
        return Result.success();
    }

    @GetMapping("/{domain}/{id}")
    public Result<Object> listAll(@PathVariable String domain, @PathVariable String id) {
        return Result.success(crudCtrlService.get(domain, id));
    }

    @GetMapping("/{domain}")
    public Result<AmisPage<Object>> listAll(@PathVariable String domain, int page, int perPage, @RequestParam(defaultValue = "id") String orderBy, @RequestParam(defaultValue = "desc") String orderDir, HttpServletRequest request) {
        PageRequest pageRequest = PageRequest.of(page - 1, perPage, Sort.by(Sort.Direction.valueOf(orderDir.toUpperCase()), orderBy));
        Page<Object> objectPage = crudCtrlService.findAll(domain, request, pageRequest);
        return Result.success(AmisPage.of(objectPage));
    }

    @GetMapping("/{domain}/list")
    public Result<List<Object>> listAll(@PathVariable String domain, @RequestParam(defaultValue = "id") String orderBy, @RequestParam(defaultValue = "desc") String orderDir, HttpServletRequest request) {
        List<Object> objectList = crudCtrlService.listAll(domain, request, Sort.by(Sort.Direction.valueOf(orderDir.toUpperCase()), orderBy));
        return Result.success(objectList);
    }

    @GetMapping("/{domain}/options")
    public Result<Map<String, Object>> listOptions(@PathVariable String domain, HttpServletRequest request) {
        List<Object> objectList = crudCtrlService.listAll(domain, request, Sort.by(Sort.Direction.DESC, "id"));
        List<JSONObject> list = objectList.stream().map(o -> {
            JSONObject option = new JSONObject();
            JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(o));
            if (jsonObject.containsKey("id")) {
                option.put("value", jsonObject.getString("id"));
            }
            if (jsonObject.containsKey("name")) {
                option.put("label", jsonObject.getString("name"));
            }
            return option;
        }).collect(Collectors.toList());

        JSONObject options = new JSONObject();
        options.put("options", list);

        return Result.success(options);
    }

}
